﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace CrazyDrawShape
{
    /// <summary>
    /// DrawCircleControl.xaml 的交互逻辑
    /// </summary>
    public partial class DrawCircleControl : UserControl
    {
        private enum DrawType
        {
            Draw,
            Edit
        }
        private enum EditType
        {
            Edge,
            Internal,
            None
        }
        Path circle = new Path { Stroke = Brushes.Red, StrokeThickness = 2, Fill = Brushes.AliceBlue, Opacity = 0.5, ClipToBounds = true };
        bool isDown = false;
        Point downPoint;
        DrawType drawType = DrawType.Draw;
        EditType editType = EditType.None;

        public DrawCircleControl()
        {
            InitializeComponent();
        }

        private void DrawClick(object sender, RoutedEventArgs e)
        {
            this.drawType = DrawType.Draw;
        }

        private void EditClick(object sender, RoutedEventArgs e)
        {
            this.drawType = DrawType.Edit;
        }

        private double PPDistance(Point p1, Point p2)
        {
            return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
        }

        private EditType GetEditType(Point point)
        {
            EllipseGeometry data = (EllipseGeometry)this.circle.Data;
            double distance = 5;
            if (Math.Abs(PPDistance(point, data.Center) - data.RadiusX) < distance)
            {
                return EditType.Edge;
            }
            else if (PPDistance(point, data.Center) < data.RadiusX)
            {
                return EditType.Internal;
            }
            else
            {
                return EditType.None;
            }
        }

        private void GridMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                this.downPoint = e.GetPosition(mainGrid);
                this.isDown = true;
                switch (this.drawType)
                {
                    case DrawType.Draw:
                        mainGrid.Children.Clear();
                        mainGrid.Children.Add(this.circle);
                        this.circle.Data = null;
                        break;
                    case DrawType.Edit:
                        this.editType = GetEditType(this.downPoint);
                        break;
                }
            }
        }

        private void GridMouseUp(object sender, MouseButtonEventArgs e)
        {
            this.isDown = false;
            this.editType = EditType.None;
        }

        private void GridMouseMove(object sender, MouseEventArgs e)
        {
            if (this.isDown)
            {
                switch (this.drawType)
                {
                    case DrawType.Draw:
                        {
                            double radius = PPDistance(this.downPoint, e.GetPosition(mainGrid));
                            this.circle.Data = new EllipseGeometry { RadiusX = radius, RadiusY = radius, Center = this.downPoint };
                        }
                        break;
                    case DrawType.Edit:
                        Point curPoint = e.GetPosition(mainGrid);
                        switch (this.editType)
                        {
                            case EditType.Edge:
                                {
                                    EllipseGeometry data = (EllipseGeometry)this.circle.Data;
                                    double radius = PPDistance(data.Center, e.GetPosition(mainGrid));
                                    data.RadiusX = data.RadiusY = radius;
                                }
                                break;
                            case EditType.Internal:
                                {
                                    double diffX = curPoint.X - this.downPoint.X;
                                    double diffY = curPoint.Y - this.downPoint.Y;
                                    EllipseGeometry data = (EllipseGeometry)this.circle.Data;
                                    data.Center = new Point(data.Center.X + diffX, data.Center.Y + diffY);
                                    this.downPoint = curPoint;
                                }
                                break;
                            case EditType.None:
                                break;
                        }
                        break;
                }
            }
        }
    }
}